package com.coffee.sku.service.sku.impl;

import com.alibaba.fastjson.JSONObject;
import com.coffee.core.entity.Page;
import com.coffee.core.entity.PagerInfo;
import com.coffee.core.enums.ExceptionEnum;
import com.coffee.core.enums.SkuSalesInformationTypeEnum;
import com.coffee.core.exception.BusinessException;
import com.coffee.core.util.BeanUtilExt;
import com.coffee.core.util.DTOUtils;
import com.coffee.core.util.StringUtil;
import com.coffee.order.service.inquire.bean.InquireOrderPlan;
import com.coffee.sku.api.sku.query.RegionalSkuSalesInformationQuery;
import com.coffee.sku.api.sku.query.SkuSalesInformationQuery;
import com.coffee.sku.api.sku.req.SkuListReq;
import com.coffee.sku.api.sku.result.RegionalSkuResult;
import com.coffee.sku.api.sku.result.RegionalSkuSalesInformationResult;
import com.coffee.sku.api.sku.result.SkuListResult;
import com.coffee.sku.api.sku.result.SkuSalesInformationResult;
import com.coffee.sku.api.sku.service.RegionalSkuService;
import com.coffee.sku.service.sku.bean.RegionalSku;
import com.coffee.sku.service.sku.bean.RegionalSkuSalesInformation;
import com.coffee.sku.service.sku.bean.SkuCategory;
import com.coffee.sku.service.sku.bean.SkuSalesInformation;
import com.coffee.sku.service.sku.dao.RegionalSkuDao;
import com.coffee.sku.service.sku.dao.RegionalSkuSalesInformationDao;
import com.coffee.sku.service.sku.dao.SkuCategoryDao;
import com.coffee.sku.service.sku.dao.SkuSalesInformationDao;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


@DubboService(dynamic = true)
public class RegionalSkuServiceImpl implements RegionalSkuService {
    private final static Logger LOG = LoggerFactory.getLogger(RegionalSkuServiceImpl.class);
    @Resource
    private RegionalSkuDao regionalSkuDao;
    @Resource
    private RegionalSkuSalesInformationDao regionalSkuSalesInformationDao;
    @Resource
    private SkuCategoryDao skuCategoryDao;
    @Resource
    private SkuSalesInformationDao skuSalesInformationDao;

    @Override
    public Page<SkuListResult> getPager(SkuListReq param, PagerInfo pr) {
        Page<SkuListResult> pager = new Page<SkuListResult>(pr.getStart(), pr.getPageSize());
        Integer count = regionalSkuDao.count(param);
        pager.setTotalPage(count);
        if (count > 0) {
            LOG.info("param===" + JSONObject.toJSONString(param));
            List<SkuListResult> page = regionalSkuDao.page(param, pr.getStart(), pr.getPageSize());
            LOG.info("page===" + JSONObject.toJSONString(page));
            for (SkuListResult skuListRep : page) {
                if (StringUtils.isNotEmpty(skuListRep.getPidPath())) {
                    String[] split = skuListRep.getPidPath().split(",");
                    SkuCategory skuCategory = skuCategoryDao.findById(Integer.parseInt(split[0]));
                    if (skuCategory != null) {
                        skuListRep.setCategoryName(skuCategory.getName());
                    }
                }
            }
            pager.setData(page);
        }
        return pager;
    }


    @Override
    public void delete(Integer id) {
        regionalSkuDao.deleteById(id);
    }

    @Override
    public void deleteBySkuId(Integer skuId) {
        regionalSkuDao.deleteBySkuId(skuId);
        regionalSkuSalesInformationDao.deleteBySkuId(skuId, SkuSalesInformationTypeEnum.GENERAL.getCode(), null);
    }

    @Override
    public void addOrUpdate(RegionalSkuResult result) throws BusinessException {
        RegionalSku item = new RegionalSku();
        BeanUtilExt.copyProperties(item, result);
        if (item.getId() == null) {
            regionalSkuDao.insert(item);
        } else {
            RegionalSku tmp = regionalSkuDao.findById(item.getId());
            if (tmp == null) {
                throw new BusinessException(ExceptionEnum.ERROR_0002.getCode(), ExceptionEnum.ERROR_0002.getMessage());
            }
            regionalSkuDao.updateById(item);
        }
    }

    @Override
    public Map<Integer, RegionalSkuResult> getItemMap(Set<Integer> idSet) {
        Map<Integer, RegionalSkuResult> map = new HashMap<Integer, RegionalSkuResult>();
        List<RegionalSku> list = regionalSkuDao.findByIds(StringUtil.setToList(idSet));
        List<RegionalSkuResult> resultList = DTOUtils.convertList(list, RegionalSkuResult.class);
        for (RegionalSkuResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBySkuIds(Integer skuId,String isMembersExclusive, List<RegionalSkuSalesInformationResult> regionalSkuSalesInformationResults) throws BusinessException {
        LOG.info("regionalSkuSalesInformationResults===" + JSONObject.toJSONString(regionalSkuSalesInformationResults));
        RegionalSku regionalSku = regionalSkuDao.findBySkuId(skuId);
        if (regionalSku == null) {
            RegionalSku param = new RegionalSku();
            param.setSkuId(skuId);
            param.setIsMembersExclusive(isMembersExclusive);
            regionalSkuDao.insert(param);
            List<RegionalSkuSalesInformation> regionalSkuSalesInformationList = getRegionalSkuSalesInformationList(skuId, regionalSkuSalesInformationResults);
            regionalSkuSalesInformationDao.insertBatch(regionalSkuSalesInformationList);
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBySkuIds(Integer skuId,String isMembersExclusive, List<RegionalSkuSalesInformationResult> regionalSkuSalesInformationResults) throws BusinessException {
        if (isMembersExclusive!=null){
            RegionalSku regionalSku=new RegionalSku();
            regionalSku.setSkuId(skuId);
            regionalSku.setIsMembersExclusive(isMembersExclusive);
            regionalSkuDao.updateBySkuId(regionalSku);
        }
        regionalSkuSalesInformationDao.deleteBySkuId(skuId, SkuSalesInformationTypeEnum.GENERAL.getCode(), null);
        List<RegionalSkuSalesInformation> regionalSkuSalesInformationList = getRegionalSkuSalesInformationList(skuId, regionalSkuSalesInformationResults);
        regionalSkuSalesInformationDao.insertBatch(regionalSkuSalesInformationList);
    }

    @Override
    public SkuListResult getSkuListResult(Integer skuId) {
        List<SkuSalesInformationResult> newList = new ArrayList<>();
        SkuListResult skuListResult = regionalSkuDao.getSkuListResult(skuId);
        SkuSalesInformationQuery skuSalesInformationQuery = new SkuSalesInformationQuery();
        skuSalesInformationQuery.setSkuId(skuId);
        List<SkuSalesInformation> skuSalesInformations = skuSalesInformationDao.list(skuSalesInformationQuery);
        List<SkuSalesInformationResult> skuSalesInformationResults = DTOUtils.convertList(skuSalesInformations, SkuSalesInformationResult.class);
        Map<Integer, SkuSalesInformationResult> skuSalesInformationMap = skuSalesInformationResults.stream().collect(Collectors.toMap(SkuSalesInformationResult::getId, i -> i));
        List<RegionalSkuSalesInformationResult> skuSalesInformationId = regionalSkuSalesInformationDao.findSkuSalesInformationId(skuId, SkuSalesInformationTypeEnum.GENERAL.getCode());
        RegionalSkuSalesInformationQuery regionalSkuSalesInformationQuery = new RegionalSkuSalesInformationQuery();
        regionalSkuSalesInformationQuery.setSkuId(skuId);
        List<RegionalSkuSalesInformation> list = regionalSkuSalesInformationDao.list(regionalSkuSalesInformationQuery);
        Map<String, RegionalSkuSalesInformation> collect = list.stream().collect(Collectors.toMap(regionalSkuSalesInformation -> regionalSkuSalesInformation.getSkuSalesInformationId() + "," + regionalSkuSalesInformation.getGtRegionId(), r -> r, (v1, v2) -> v2));
        for (RegionalSkuSalesInformationResult regionalSkuSalesInformationResult : skuSalesInformationId) {
            SkuSalesInformationResult skuSalesInformation = skuSalesInformationMap.get(regionalSkuSalesInformationResult.getSkuSalesInformationId());
            if (skuSalesInformation == null) {
                continue;
            }
            SkuSalesInformationResult skuSalesInformationResult = new SkuSalesInformationResult();
            BeanUtilExt.copyProperties(skuSalesInformationResult, skuSalesInformation);
            skuSalesInformationResult.setPrice(regionalSkuSalesInformationResult.getRegionalPrice());
            skuSalesInformationResult.setGtRegionIds(regionalSkuSalesInformationResult.getGtRegionIds());
            skuSalesInformationResult.setGtRegionNames(regionalSkuSalesInformationResult.getGtRegionNames());
            skuSalesInformationResult.setRemark(collect.get(skuSalesInformation.getId() + "," + regionalSkuSalesInformationResult.getGtRegionIds().get(0)).getRemark());
            skuSalesInformationResult.setIntegralDeduction(collect.get(skuSalesInformation.getId() + "," + regionalSkuSalesInformationResult.getGtRegionIds().get(0)).getIntegralDeduction());
            skuSalesInformationResult.setProportion(collect.get(skuSalesInformation.getId() + "," + regionalSkuSalesInformationResult.getGtRegionIds().get(0)).getProportion());
            newList.add(skuSalesInformationResult);
        }
        skuListResult.setSkuSalesInformationResults(newList);
        return skuListResult;
    }

    public List<RegionalSkuSalesInformation> getRegionalSkuSalesInformationList(Integer skuId, List<RegionalSkuSalesInformationResult> regionalSkuSalesInformationResults) {
        List<RegionalSkuSalesInformation> regionalSkuSalesInformationList = new ArrayList<>();
        for (RegionalSkuSalesInformationResult regionalSkuSalesInformationResult : regionalSkuSalesInformationResults) {
            List<Integer> gtRegionIds = regionalSkuSalesInformationResult.getGtRegionIds();
            for (Integer gtRegionId : gtRegionIds) {
                RegionalSkuSalesInformation regionalSkuSalesInformation = new RegionalSkuSalesInformation();
                regionalSkuSalesInformation.setSkuId(skuId);
                regionalSkuSalesInformation.setGtRegionId(gtRegionId);
                regionalSkuSalesInformation.setSkuSalesInformationId(regionalSkuSalesInformationResult.getSkuSalesInformationId());
                regionalSkuSalesInformation.setRegionalPrice(regionalSkuSalesInformationResult.getRegionalPrice());
                regionalSkuSalesInformation.setRemark(regionalSkuSalesInformationResult.getRemark());
                if (regionalSkuSalesInformationResult.getIntegralDeduction() != null) {
                    regionalSkuSalesInformation.setIntegralDeduction(regionalSkuSalesInformationResult.getIntegralDeduction());
                }
                if (regionalSkuSalesInformationResult.getProportion() != null) {
                    regionalSkuSalesInformation.setProportion(regionalSkuSalesInformationResult.getProportion());
                }
                regionalSkuSalesInformationList.add(regionalSkuSalesInformation);
            }
        }
        Collections.reverse(regionalSkuSalesInformationList);
        ArrayList<RegionalSkuSalesInformation> collect = regionalSkuSalesInformationList.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(()
                        -> new TreeSet<>(Comparator.comparing(u -> u.getSkuSalesInformationId() + "#" + u.getGtRegionId()))), ArrayList::new));
        return collect;
    }

}
